package com.ieasy.basic.util.spring.mail;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;


/**
 * 邮件发送工具
 * @author Administrator
 *
 */
@Component
public class MailKit {
	
	private static final Logger logger = LoggerFactory.getLogger(MailKit.class) ;

	@Autowired
	private JavaMailSender sender ;
	
	@Autowired
	private TaskExecutor taskExecutor; //注入Spring封装的异步执行器
	
	
	/**
	 * 异步发送邮件
	 * @param mailBean
	 */
	public void sendAsync(final MailBean mailBean) {
		taskExecutor.execute(new Runnable() {
			@Override
			public void run() {
				sendSynch(mailBean);
			}
		}) ;
	}
	
	/**
	 * 同步发送邮件
	 * @param mailBean
	 */
	public void sendSynch(MailBean mailBean) {
		try {
			if(null != mailBean) {
				logger.debug("********************************发送电子邮件*********************************");
				logger.debug("标题：" + mailBean.getSubject()) ;
				logger.debug("发件人：" + mailBean.getFrom()) ;
				logger.debug("------------------------------------------------------------------------");
				
				MimeMessage mimeMessage = sender.createMimeMessage();
				MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8");
				
				messageHelper.setFrom(mailBean.getFrom());
				setTo(mailBean, mimeMessage);	//收件
				setCc(mailBean, mimeMessage);	//抄送
				setBcc(mailBean, mimeMessage);	//暗送
				messageHelper.setSubject(mailBean.getSubject());
				messageHelper.setText(mailBean.getContent(), true);
				
				//附件
				setAttachment(messageHelper, mailBean.getAttachments(), mailBean.getAttachmentsArray(), mailBean.getAttachmentsString());
				
				//发送邮件
				this.sender.send(mimeMessage);
				logger.debug("*********************************邮件发送完成********************************");
			} else {
				logger.debug("邮件数据载体为空");
			}
		} catch (Exception e) {
			logger.error("发生异常：", e);
		}
	}
	
	
	//附件
	public void setAttachment(MimeMessageHelper messageHelper, File[] attachment, String[] attachmentArray, String attachmentString) throws MessagingException {
		//附件，文件对象
		if(null != attachment) {
			for(File file : attachment) {
				messageHelper.addAttachment(file.getName(), file);
				logger.debug("附件信息==》" + file.getName());
			}
		}
		
		//附件，字符串路径数组
		if(null != attachmentArray) {
			for (String path : attachmentArray) {
				File file = new File(path) ;
				messageHelper.addAttachment(file.getName(), file);
				logger.debug("附件信息==》" + file.getName());
			}
		}
		
		//附件，文件路径方式
		if(null != attachmentString) {
			String[] filePaths = attachmentString.split(";") ;
			for (String path : filePaths) {
				File file = new File(path) ;
				messageHelper.addAttachment(file.getName(), file);
				logger.debug("附件信息==》" + file.getName());
			}
		}
	}
	
	//收件
	public void setTo(MailBean mailBean, MimeMessage mimeMessage) throws MessagingException {
		if(null != mailBean && null != mailBean.getTo() && !"".equals(mailBean.getTo())) {
			//获取所有抄送人地址
			List<InternetAddress> list = address(mailBean.getTo(), "收件") ;
			//设置可以群发和单发抄送人
			InternetAddress[] addrArray = (InternetAddress[])list.toArray(new InternetAddress[list.size()]) ;
			//设置抄送人地址
			mimeMessage.setRecipients(RecipientType.TO, addrArray) ;
		}
	}
	//抄送
	public void setCc(MailBean mailBean, MimeMessage mimeMessage) throws MessagingException {
		if(null != mailBean && null != mailBean.getCc() && !"".equals(mailBean.getCc())) {
			//获取所有抄送人地址
			List<InternetAddress> list = address(mailBean.getCc(), "抄送") ;
			//设置可以群发和单发抄送人
			InternetAddress[] addrArray = (InternetAddress[])list.toArray(new InternetAddress[list.size()]) ;
			//设置抄送人地址
			mimeMessage.setRecipients(RecipientType.CC, addrArray) ;
		}
	}
	
	//暗送
	public void setBcc(MailBean mailBean, MimeMessage mimeMessage) throws MessagingException {
		if(null != mailBean && null != mailBean.getBcc() && !"".equals(mailBean.getBcc())) {
			//InternetAddress[] addrArray = InternetAddress.parse(mailBean.getBcc());  
			//mimeMessage.setRecipients(RecipientType.BCC, addrArray) ;
			//获取所有抄送人地址
			List<InternetAddress> list = address(mailBean.getCc(), "暗送") ;
			//设置可以群发和单发抄送人
			InternetAddress[] addrArray = (InternetAddress[])list.toArray(new InternetAddress[list.size()]) ;
			//设置抄送人地址
			mimeMessage.setRecipients(RecipientType.BCC, addrArray) ;
		}
	}
	
	
	
	/**
	 * 解析邮件地址XXX@1236.com,BBB@126.com,TTT@126.com
	 * @param address
	 * @return
	 */
	public static List<InternetAddress> address(String address, String typeName) {
		List<String> successAddr = new ArrayList<String>() ;
		List<String> failerAddr = new ArrayList<String>() ;
		
		List<InternetAddress> list = new ArrayList<InternetAddress>() ;
		String[] to = address.split(",") ;
		
		for(int i=0; i<to.length; i++) {
			try {
				if(!"".equals(to[i]) && checkMail(to[i])) {
					list.add(new InternetAddress(to[i])) ;
					successAddr.add(to[i]) ;
				} else {
					failerAddr.add(to[i]) ;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		logger.debug(typeName + "成功数量：" + successAddr.size() + "   地址:" + successAddr.toString());
		logger.debug(typeName + "失败数量：" + failerAddr.size() + "   地址:" + failerAddr.toString());
		logger.debug("------------------------------------------------------------------------");
		return list ;
	}
	
	/**
	 * 正则判断Email地址是否规范
	 * @param mailAddr
	 * @return
	 */
	public static boolean checkMail(String mailAddr) {
		String regex = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*" ;
		
		Pattern pattern = Pattern.compile(regex) ;
		Matcher matcher = pattern.matcher(mailAddr) ;
		
		return matcher.matches() ;
	}
	
}

